package com.hzhr.iot.collect.protocol.flowController;

import com.hzhr.iot.collect.constant.FunctiontmpEnum;
import com.hzhr.iot.collect.constant.MessageFieldKeyEnum;
import com.hzhr.iot.collect.constant.UpDownEnum;
import com.hzhr.iot.collect.constant.entity.FunctionEntity;
import com.hzhr.iot.collect.constant.entity.constant.FunctionEntityConstant;
import com.hzhr.iot.collect.constant.entity.constant.FunctiontmpEntityConstant;
import com.hzhr.iot.collect.model.CommandResponseModel;
import com.hzhr.iot.collect.protocol.logger.Logger;
import com.hzhr.iot.collect.protocol.parser.Parser;
import com.hzhr.iot.collect.protocol.processor.MessageProcessor;
import com.hzhr.iot.collect.protocol.responder.Responder;
import com.hzhr.iot.collect.util.SpringContextUtil;
import com.hzhr.iot.core.util.HzhrJsonUtil;
import com.hzhr.iot.core.util.HzhrTypeUtil;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public abstract class FlowController {
    abstract Parser getParser();
    abstract Responder getResponder();
    abstract Logger getLogger();

    public CommandResponseModel run(String command, int protocolId, String deviceId) throws Exception {
        Parser parser = getParser();
        Responder responder = getResponder();
        Logger logger = getLogger();

        //解析
        if (parser == null) return null;
        Map<MessageFieldKeyEnum, Object> parsingResult = parser.parsing(command, protocolId, deviceId, UpDownEnum.UP);
        if (parsingResult == null) return null;
        System.out.println(HzhrJsonUtil.object2json(parsingResult));

        //记录解析日志
        logger.log(protocolId, deviceId, command, parser, UpDownEnum.UP);

        //处理
        String functionCode = HzhrTypeUtil.object2string(parsingResult.get(MessageFieldKeyEnum.FUNCTION_CODE));
        FunctionEntity functionEntity = FunctionEntityConstant.getFunctionEntityByProtocolIdAndFunctionCode(protocolId, functionCode);
        if (functionEntity == null) return null;
        Integer functionId = functionEntity.getId();
        MessageProcessor messageProcessor = (MessageProcessor) SpringContextUtil.getBean("messageProcessor" + functionId);
        List<Map<MessageFieldKeyEnum, Object>> respMsgObjList = messageProcessor.proccess(protocolId, deviceId, parsingResult);

        CommandResponseModel commandResponseModel = new CommandResponseModel();
        if (respMsgObjList != null && respMsgObjList.size() > 0) {
            //反解析响应报文对象
            List<String> respMsgList = new ArrayList<>();
            for (Map<MessageFieldKeyEnum, Object> respMsgObj :
                    respMsgObjList) {
                String respMsg = parser.inverselyParsing(respMsgObj, protocolId, deviceId, UpDownEnum.DOWN);
                respMsgList.add(respMsg);
            }

            //响应
            commandResponseModel = responder.response(respMsgList, deviceId, protocolId, functionCode, parser);

            //记录响应日志
            if (commandResponseModel != null) {
                List<String> respMsgs = commandResponseModel.getRespMsgList();
                if (respMsgs != null && respMsgs.size() > 0) {
                    for (String respMsg :
                            respMsgs) {
                        logger.log(protocolId, deviceId, respMsg, parser, UpDownEnum.DOWN);
                    }
                }
            }

        }

        return commandResponseModel;
    }
}
